package net.valerijtimakov.homefinances.dao.storages.user.mysql;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import net.valerijtimakov.homefinances.domain.common.DataItem;
import net.valerijtimakov.homefinances.domain.user.SessionItem;
import net.valerijtimakov.homefinances.exceptions.AppExceptionWrongState;
import net.valerijtimakov.homefinances.exceptions.AppPersProviderException;
import net.valerijtimakov.homefinances.exceptions.AppPersistentException;
import net.valerijtimakov.homefinances.exceptions.wrongarg.AppExceptionNullArgument;
import net.valerijtimakov.homefinances.dao.storages.common.mysql.ItemsStorage;
import net.valerijtimakov.homefinances.dao.storages.finances.mysql.IMySqlProvider;
import net.valerijtimakov.homefinances.dao.storages.user.ISessionStorage;

public class SessionStorage extends ItemsStorage implements ISessionStorage {

	
	private String userIdFieldName = "user_if";
	private String keyFieldName = "key";
	private String expiredFieldName = "expired";
	
	public SessionStorage(IMySqlProvider provider) throws AppExceptionWrongState {
		super(provider);
	}

	public Map<Long, SessionItem> getUsers(long... id) 
		throws AppPersProviderException, AppExceptionWrongState 
	{
		return getItemsByIds(id);
	}
	
	public Map<String, SessionItem> getSessionsByKeies(String ... keies) throws AppExceptionWrongState, AppPersProviderException {
		initSelect();
		selectQuery.getWhere().createListCondBuilder(keyFieldName, String.class).importFieldValues(keies);
		String query = selectQuery.getSql();
		HashMap<String, SessionItem> res = new HashMap<String, SessionItem>();
		if (query.isEmpty()) {
			return res;
		}
		try{
			provider.query(query);
			while (provider.getResultSet().next()){
				SessionItem item = new SessionItem();
				parse(provider.getResultSet(), item);
				res.put(item.getKey(), item);
			}			
			return res;
		} catch (SQLException e) {
			throw new AppPersProviderException(e);
		} finally {
			if(provider!=null) {
				provider.close();
			}
		}
	}

	public void addSession(SessionItem session) throws AppPersistentException, 
		AppExceptionNullArgument, AppExceptionWrongState 
	{
		addItem(session, "Не задан экземпляр сессии!", "Ошибка добавления сессии!");
	}

	public void removeSession(long id) throws AppPersProviderException, AppExceptionWrongState {
		delete(id);
	}

	public void updateSession(SessionItem session) throws AppPersProviderException, AppExceptionWrongState {
		update(session);
	}

	@Override
	protected String getTableName() {
		return "session";
	}

	@Override
	protected DataItem createTempItem() {
		return new SessionItem();
	}

	@Override
	protected <T extends DataItem> void parse(ResultSet rs, T item) throws SQLException {
		super.parse(rs, item);
		SessionItem cItem = (SessionItem)item;
		cItem.setUserId(rs.getLong(userIdFieldName));
		cItem.setKey(rs.getString(keyFieldName));
		cItem.setExpired(rs.getTimestamp(expiredFieldName));
	}
	
	@Override
	protected void initSelect() {
		super.initSelect();
		selectQuery.addField(userIdFieldName);
		selectQuery.addField(keyFieldName);
		selectQuery.addField(expiredFieldName);
	}

	@Override
	protected <T extends DataItem> void addData(T item) {
		SessionItem cItem = (SessionItem)item;
		insertQuery.setFieldValue(userIdFieldName, cItem.getUserId());
		insertQuery.setFieldValue(keyFieldName, cItem.getKey());
		insertQuery.setFieldValue(expiredFieldName, cItem.getExpired());
	}

	@Override
	protected <T extends DataItem> void setUpdatedFields(T item) {
		SessionItem cItem = (SessionItem)item;
		updateQuery.setFieldValue(userIdFieldName, cItem.getUserId());
		updateQuery.setFieldValue(keyFieldName, cItem.getKey());
		updateQuery.setFieldValue(expiredFieldName, cItem.getExpired());
	}
}
